package physics.globalforce;

import physics.Assembly;
import physics.EnvironmentSingleton.EnvironmentalForce;
import physics.Force;
import physics.component.Mass;


/**
 * Interface for an global/environmental force.
 *
 * @author Kevin Gao, Connor Gordon
 *
 */
public abstract class GlobalForce {

    /**
     * Type of environmental force.
     */
    private final EnvironmentalForce myForceType;

    /**
     * Constructor for GlobalForce, used to set type.
     *
     * @param ef Type of force
     */
    public GlobalForce (final EnvironmentalForce ef) {
        myForceType = ef;
    }

    /**
     * Calculates the force to be applied to a mass.
     *
     * @param target Mass to apply force on
     * @param asm Assembly that mass is part of
     * @return Force that should be applied on mass
     */
    protected abstract Force getCalculatedForce (Mass target, Assembly asm);

    /**
     * Applies the global force on a target mass, given assembly as context.
     *
     * @param target Mass to apply force on
     * @param asm Assembly that mass is part of
     */
    public final void applyForce (final Mass target, final Assembly asm) {
        target.applyForce(getCalculatedForce(target, asm));
    }

    /**
     * Getter for myForceType.
     *
     * @return EnvironmentalForce type corresponding to this GlobalForce
     */
    public final EnvironmentalForce getForceType () {
        return myForceType;
    }

    /**
     * This method may be overwritten for more granular control over which
     * forces are enabled.
     *
     * @return true if force is enabled, false if not enabled
     */
    public boolean isEnabled () {
        return true;
    }

}
